#include "Leaves.h"
#include <D3DX11.h>
#include <time.h>


Leaves::Leaves() :	Mesh(), bActive(false), bFirstRun(true), srv_noise_texture(0), vb_init(0), vb_elements(0), vb_elements_2(0), 
					IA_Leaf(0), IA_Draw(0), fx_m_World(0), fx_m_WorldViewProj(0), fx_m_L_ViewProj(0), fx_tex_shadow_map(0), fx_lights(0), 
					fx_num_lights(0), fx_pEye(0), fx_bShadowed(0), fx_bUsePCSS(0), m_bFinishedAnimation(false),
					m_bLeavesDrop(false), vb_ID(0)
{
	bActive = true;
	setNumSubsets(1);
}


Leaves::~Leaves()
{
	try
	{
		if (srv_noise_texture)
			srv_noise_texture->Release();
		if (vb_init)
			vb_init->Release();
		if (vb_elements)
			vb_elements->Release();
		if (vb_elements_2)
			vb_elements_2->Release();
		if (IA_Leaf)
			IA_Leaf->Release();
		if (IA_Draw)
			IA_Draw->Release();
		if (vb_ID)
			vb_ID->Release();
	}
	catch(...)
	{
		MessageBoxA(0, "Exception thrown in Leaves destructor", 0, 0);
	}
}





void Leaves::init(const char* filename, ID3D11Device* g_device, ID3D11DeviceContext* g_context)
{
	#ifndef PIX

	// effect
	createEffect("../Desert_Island/shaders/leaves10.fxo", g_device);
	
	Mesh::init(NULL, g_device, g_context);
	
	// set material values 
	Mesh::setExponent(1.0f);
	Mesh::setCutOffAngle(8.0f);
	Mesh::setDiffuse(0.1f, 0.3f, 0.1f);
	Mesh::setSpecular(1.0f, 1.0f, 1.0f);
	Mesh::createDiffuseTexture(L"../Desert_Island/media/leaf.jpg");
	

	// Fire
	m_numSubsets = 32;
	createEffect("../Desert_Island/shaders/leavesEmitters.fxo", g_device, &m_fxGenEmitters);
	//////////

	// Leaves matrices
	XMMATRIX mtxI = XMMatrixIdentity();

	for (UINT i=0; i<N_LEAVES; i++) 
		XMStoreFloat4x4(&(mtxLeaves[i]), mtxI);

	// Input layout - Leaf IA
	D3D11_INPUT_ELEMENT_DESC leaf_layout[] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TYPE", 0, DXGI_FORMAT_R32_UINT                     , 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "LENGTH", 0, DXGI_FORMAT_R32_FLOAT                    , 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "INTERVAL",	  0, DXGI_FORMAT_R32_FLOAT                    , 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "ID",	  0, DXGI_FORMAT_R32_UINT                    , 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	D3DX11_PASS_DESC passDesc;
	ID3DX11EffectTechnique* tech = getFX()->GetTechniqueByName("Leaves_SO");
	tech->GetPassByIndex(0)->GetDesc(&passDesc);

	HRESULT hr = g_device->CreateInputLayout(leaf_layout, 5, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &IA_Leaf);
	if (FAILED(hr))
		MessageBoxA(0, "Error creating IA leaves", 0, 0);
	////////////////////////////////////////////////////////////////

	// Input layout - Vertex IA
	D3D11_INPUT_ELEMENT_DESC vertex_layout[] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0,  DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TANGENT", 0,  DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEX_COORDS", 0,  DXGI_FORMAT_R32G32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	tech = getFX()->GetTechniqueByName("Leaves_Draw");
	tech->GetPassByIndex(0)->GetDesc(&passDesc);

	if (FAILED(hr))
		MessageBoxA(0, "Error creating IA leaves - vertex", 0, 0);
	

	////////////////////////////////////////////////////////////////

	D3D11_INPUT_ELEMENT_DESC vertex_layout_Draw[] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0,  DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TANGENT", 0,  DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEX_COORDS", 0,  DXGI_FORMAT_R32G32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	tech = getFX()->GetTechniqueByName("Leaves_Draw");
	tech->GetPassByIndex(0)->GetDesc(&passDesc);

	hr = g_device->CreateInputLayout(vertex_layout_Draw, /*5*/4, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &IA_Draw);

	if (FAILED(hr))
		MessageBoxA(0, "Error creating leaves IA Draw", 0, 0);



	////////////////////////////////////////////////////////////////

	

	// Buffers - Init buffer
	D3D11_BUFFER_DESC vb_desc;
	vb_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vb_desc.ByteWidth = sizeof(LeafElement);
	vb_desc.CPUAccessFlags = vb_desc.MiscFlags = 0;
	vb_desc.StructureByteStride = 0;
	vb_desc.Usage = D3D11_USAGE_DEFAULT;

	LeafElement p[1];

	p[0].length = 0.0f;
	p[0].pos = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
	p[0].type = Leaves::LEAF_GENERATOR;
	p[0].interval = 0.0f;
	p[0].id = 0;

	D3D11_SUBRESOURCE_DATA vb_data;
	vb_data.pSysMem = p;
	vb_data.SysMemPitch = vb_data.SysMemSlicePitch = 0;

	hr = g_device->CreateBuffer(&vb_desc, &vb_data, &vb_init);
	if (FAILED(hr))
		MessageBoxA(0, "Error creating leaves init buffer", 0, 0);

	//////////////////////////////

	vb_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
	vb_desc.ByteWidth = sizeof(LeafElement) * MAX_ELEMENTS * 100;

	hr = g_device->CreateBuffer(&vb_desc, 0, &vb_elements);
	if (FAILED(hr))
		MessageBoxA(0, "Error creating leaves buffer", 0, 0);

	hr = g_device->CreateBuffer(&vb_desc, 0, &vb_elements_2);
	if (FAILED(hr))
		MessageBoxA(0, "Error creating leaves buffer 2", 0, 0);
	///////////////////////////////

	// ID buffer
	ZeroMemory(&vb_desc, sizeof(vb_desc));
	vb_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
	vb_desc.ByteWidth = sizeof(UINT) * MAX_ELEMENTS * 100;
	vb_desc.Usage = D3D11_USAGE_DEFAULT;

	hr = g_device->CreateBuffer(&vb_desc, 0, &vb_ID);
	if (FAILED(hr))
		MessageBoxA(0, "Error creating leaves ID buffer", 0, 0);
	//----------------------------


	hr = D3DX11CreateShaderResourceViewFromFile(g_device, L"../Desert_Island/media/noise_texture.jpg", NULL, NULL, &srv_noise_texture, 0);
	if (FAILED(hr))
		MessageBoxA(0, "Error create noise texture SRV", 0, 0);

	////////////


	fx_m_World				= getFX()->GetVariableByName("m_World")->AsMatrix();
	fx_m_WorldViewProj		= getFX()->GetVariableByName("m_WorldViewProj")->AsMatrix();
	fx_m_L_ViewProj			= getFX()->GetVariableByName("m_L_ViewProj")->AsMatrix();

	fx_tex_shadow_map		= getFX()->GetVariableByName("tex_shadow_map")->AsShaderResource();

	fx_lights				= getFX()->GetVariableByName("lights");

	fx_num_lights			= getFX()->GetVariableByName("num_lights")->AsScalar();

	fx_pEye					= getFX()->GetVariableByName("pEye")->AsVector();
	fx_bShadowed			= getFX()->GetVariableByName("bShadowed")->AsScalar();
	fx_bUsePCSS				= getFX()->GetVariableByName("bUsePCSS")->AsScalar();

#endif
}
		

void Leaves::Update(float dt)
{
#ifndef PIX
	static float duration = 5.0f;

	if (!bActive) return;


	if (m_bLeavesDrop) {
		for (int i=0; i<N_LEAVES; i++) {
			// translation
			mtxLeaves[i]._42 -= 0.25f * dt;
		}
		duration -= dt * 2.0f;

		if (duration <= 0.0f || mtxLeaves[0]._42 < -3.5f) {
			duration = 5.0f;
			setActive(false);
			return;
		}
	}



	// Swap buffers' addresses
	if (!bFirstRun) {
		ID3D11Buffer* tmp;
		tmp = vb_elements;
		vb_elements = vb_elements_2;
		vb_elements_2 = tmp;
	}
	else // first time-build leaves matrices
	{
		srand((unsigned int)time(NULL));
		float vals[N_LEAVES];
		float y_min = 3.1f, y_range = 1.0f;
		float r = 0.15f;

		float angle_step = 2.0f*3.1415f / (float)N_LEAVES;

		for (int i=0; i<N_LEAVES; i++) {
			vals[i] = y_min + (rand() / (float)RAND_MAX) * 0.4f;
			
			// get random variable theta : 0 <= theta <= 360 
			float theta = i * angle_step;
			computeLeafMatrix(XMFLOAT3(r*cos(theta), vals[i], r*sin(theta)), i);
		}
		ID3DX11EffectScalarVariable* fxHeight = getFX()->GetVariableByName("arrLeavesHeights")->AsScalar(); 
		fxHeight->SetFloatArray((float*)&vals, 0, 32);
	}
	
	

	// Save state
	ID3D11InputLayout* current_IA;
	context()->IAGetInputLayout(&current_IA);

	D3D11_PRIMITIVE_TOPOLOGY current_primitive_topology;
	context()->IAGetPrimitiveTopology(&current_primitive_topology);
	//////////////////////////////////////////////////////////////////////////

	// Set Topology
	context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
	
	// set input layout 
	context()->IASetInputLayout(IA_Leaf);
	
	// Set Vertex Buffer
	UINT stride = sizeof(LeafElement);
	UINT offset = 0;
	
	
	// First Pass : update leafElements - stream out 

	// Set effect Variables
	ID3DX11EffectMatrixVariable* fx_m_WVP;
	ID3DX11EffectShaderResourceVariable* fx_noise_texture;

		fx_m_WVP = getFX()->GetVariableByName("m_WVP")->AsMatrix();
		//fx_m_WVP->SetMatrix((float*)&mWVP);
		
		fx_noise_texture = getFX()->GetVariableByName("noise_texture")->AsShaderResource();
		fx_noise_texture->SetResource(srv_noise_texture);


	ID3DX11EffectScalarVariable*	fx_dt = getFX()->GetVariableByName("dt")->AsScalar();
	fx_dt->SetFloat(dt);

	ID3DX11EffectScalarVariable*	fx_grow_speed = getFX()->GetVariableByName("grow_speed")->AsScalar();
	fx_grow_speed->SetFloat(0.1f);
		
		
	// Get technique - Draw()
	ID3DX11EffectTechnique* tech = getFX()->GetTechniqueByName("Leaves_SO");
	
	tech->GetPassByIndex(0)->Apply(0, context());
	

	
#define _stats



	if (bFirstRun) 
	{
		context()->IASetVertexBuffers(0, 1, &vb_init, &stride, &offset);
		// Set Stream-Out Buffer
		context()->SOSetTargets(1, &vb_elements_2, &offset);	
		context()->Draw(1, 0);
		bFirstRun = false;
	}
	else
	{
		context()->IASetVertexBuffers(0, 1, &vb_elements, &stride, &offset);
		// Set Stream-Out Buffer
		context()->SOSetTargets(1, &vb_elements_2, &offset);	
		context()->DrawAuto();
	}






	// Un-bind Stream-Out Buffer
	ID3D11Buffer* buff_empty[1] =  {0};
	context()->SOSetTargets(1, buff_empty, &offset);
	

	duration += dt * /*grow_speed*/0.1f;
	if (duration > 1.0f) {
		m_bFinishedAnimation = true;
	}
	
	///////////////////////////////////////////////////////////


	// Second Pass : particles to trianglelist	
	
	// Set Vertex Buffer
	context()->IASetVertexBuffers(0, 1, &vb_elements_2, &stride, &offset);
	
	// Set Stream-Out Buffers for geometry and leaf ID
	ID3D11Buffer* so_buffers[2] = { vb_elements, vb_ID };
	UINT offsets[2] = { 0, 0 };
	context()->SOSetTargets(2, so_buffers, offsets);	


	// Get Technique - Draw()
	tech = getFX()->GetTechniqueByName("Leaves_SO_Geometry");
	tech->GetPassByIndex(0)->Apply(0, context());

	// draw geometry info
	context()->DrawAuto();

	// Un-bind Stream-Out Buffer
	ID3D11Buffer* buffers_null[2] = { 0, 0 };
	context()->SOSetTargets(2, buffers_null, offsets);


	// Restore state
	context()->IASetPrimitiveTopology(current_primitive_topology);
	if (current_IA) {
		context()->IASetInputLayout(current_IA);
		current_IA->Release();
	}

#endif
}


void Leaves::draw(const Camera& camera, const vector<Light*>& lights)
{
#ifndef PIX	
	
	if (!bActive) return;

	// Material
	Mesh::setMaterial(getFX());

	context()->IASetInputLayout(IA_Draw);

	// World Matrix
	XMMATRIX mWorld = XMLoadFloat4x4(&(mtxWorld()));
	fx_m_World->SetMatrix((float*)&mWorld);
	fx_m_WorldViewProj->SetMatrix((float*)&(mWorld * camera.getViewMatrix() * camera.getProjectionMatrix()));
	fx_pEye->SetFloatVector((float*)&(camera.getPosVector3()));

	// Light // mView, shadow_map, light params
	for (unsigned int i=0; i<lights.size(); ++i)
	{
		fx_m_L_ViewProj =	getFX()->GetVariableByName("m_L_ViewProj")->GetElement(i)->AsMatrix();
		fx_lights =			getFX()->GetVariableByName("lights")->GetElement(i);
		fx_tex_shadow_map = getFX()->GetVariableByName("tex_shadow_map")->GetElement(i)->AsShaderResource();
		
		fx_m_L_ViewProj->SetMatrix(		(float*)&(lights[i]->getViewProjMatrix())	);
		fx_tex_shadow_map->SetResource(	lights[i]->getShadowMapSRV());
		fx_lights->SetRawValue(	(void*)&(lights[i]->getLightStructure()), 0, sizeof(Light_Params)	);
	}
	ID3DX11EffectScalarVariable*	fx_shadow_size = getFX()->GetVariableByName("shadow_size")->AsScalar();
	fx_shadow_size->SetInt(lights[0]->getShadowMapSize());
	fx_num_lights->SetInt(lights.size());

	fx_bShadowed->SetBool(false);
	fx_bUsePCSS->SetBool(PCSS());

	// Leaves Matrices
	ID3DX11EffectMatrixVariable* fx_mtxLeaves = 0;
	for (int i=0; i<N_LEAVES; i++) {
		fx_mtxLeaves = getFX()->GetVariableByName("mtxLeaves")->GetElement(i)->AsMatrix();
		fx_mtxLeaves->SetMatrix((float*)&(mtxLeaves[i]));
	}

	// Set Vertex Buffer
	UINT stride = sizeof(Vertex);
	UINT offset = 0;


	// Set Vertex Buffer
	ID3DX11EffectTechnique* tech = getFX()->GetTechniqueByName("Leaves_Draw");

	// draw geometry info
	draw(0, getFX(), "Leaves_Draw");

	ID3D11Buffer* buffer_empty[1] = { 0 };
	context()->IASetVertexBuffers(0, 1, buffer_empty, &stride, &offset);

	// --------

	for (unsigned int i=0; i<lights.size(); ++i) {
		fx_tex_shadow_map = getFX()->GetVariableByName("tex_shadow_map")->GetElement(i)->AsShaderResource();
		fx_tex_shadow_map->SetResource(0);
	}
	tech->GetPassByIndex(0)->Apply(0, context());

#endif
}

XMMATRIX Leaves::getWorldMatrix(int subset) const
{	
	return XMLoadFloat4x4(&mtxLeaves[subset]);
}

XMFLOAT4X4 Leaves::getSubsetMatrix(UINT subset) const
{
	return mtxLeaves[subset];
}


void Leaves::draw(int subset, ID3DX11Effect* fx, const char* technique) const
{
#ifndef PIX
	if (!bActive) return;

	context()->IASetInputLayout(IA_Draw);
	// Set Vertex Buffer
	UINT stride = sizeof(Vertex);
	UINT offset = 0;
	
	// Set Vertex Buffer
	context()->IASetVertexBuffers(0, 1, &vb_elements, &stride, &offset);

	ID3DX11EffectTechnique* tech = fx->GetTechniqueByName(technique);
	tech->GetPassByIndex(0)->Apply(0, context());
	
	
	
#ifdef _stats
	D3D11_QUERY_DESC queryDesc;
	queryDesc.Query = D3D11_QUERY_PIPELINE_STATISTICS;
	queryDesc.MiscFlags = 0;

	ID3D11Query* pQuery;
	g_dev()->CreateQuery(&queryDesc, &pQuery);
	context()->Begin(pQuery);
#endif




context()->DrawAuto();


#ifdef _stats
	context()->End(pQuery);
	while( S_FALSE == context()->GetData(pQuery, NULL, 0, 0) ) {}
	D3D11_QUERY_DATA_PIPELINE_STATISTICS so_data;
	HRESULT hr = context()->GetData(pQuery, &so_data, sizeof(so_data), 0);
	pQuery->Release();
#endif


	ID3D11Buffer* buffer_empty[1] = { 0 };
	context()->IASetVertexBuffers(0, 1, buffer_empty, &stride, &offset);

#endif
}



void Leaves::setActive(bool v) 
{ 
	if (v) {
		m_bFinishedAnimation = false; 
		m_bLeavesDrop = false;

	}
	else  {
		m_bLeavesDrop = true;
		setFirstRun(true);
		XMMATRIX mtxI = XMMatrixIdentity();
		for (UINT i=0; i<N_LEAVES; i++) 
			XMStoreFloat4x4(&(mtxLeaves[i]), mtxI);
	}

	bActive = v; 
}


void Leaves::generateEmitters(UINT subset, UINT global_ID, ID3DX11Effect* fxDefault, const char* techDefault)
{
#ifndef PIX

	if (subset >= 1)
		return;

	// Save state
	ID3D11InputLayout* current_IA;
	context()->IAGetInputLayout(&current_IA);
	D3D11_PRIMITIVE_TOPOLOGY current_primitive_topology;
	context()->IAGetPrimitiveTopology(&current_primitive_topology);
	////////////////

	
	context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
	context()->IASetInputLayout(IA_Leaf);
	
	UINT stride = sizeof(LeafElement);
	UINT offset = 0;
	context()->IASetVertexBuffers(0, 1, &vb_elements_2, &stride, &offset);

	ID3DX11EffectScalarVariable* fx_iGlobalID = m_fxGenEmitters->GetVariableByName("iGlobalID")->AsScalar();
	fx_iGlobalID->SetInt(global_ID);

	
#define _stats
#ifdef _stats
	D3D11_QUERY_DESC queryDesc;
	queryDesc.Query = D3D11_QUERY_SO_STATISTICS;
	queryDesc.MiscFlags = 0;

	ID3D11Query* pQuery;
	g_dev()->CreateQuery(&queryDesc, &pQuery);
	context()->Begin(pQuery);
#endif


	ID3DX11EffectTechnique* tech = m_fxGenEmitters->GetTechniqueByName("LeavesEmitters");
	tech->GetPassByIndex(0)->Apply(0, context());
	
	// draw geometry info
	context()->DrawAuto();

	ID3D11Buffer* buffer_empty[1] = { 0 };
	context()->IASetVertexBuffers(0, 1, buffer_empty, &stride, &offset);


#ifdef _stats
	context()->End(pQuery);
	
	while( S_FALSE == context()->GetData(pQuery, NULL, 0, 0) )
	{
	}

	D3D11_QUERY_DATA_SO_STATISTICS so_data;
	so_data.NumPrimitivesWritten = so_data.PrimitivesStorageNeeded = 0;
	HRESULT hr = context()->GetData(pQuery, &so_data, sizeof(so_data), 0);

	pQuery->Release();
#endif



	///////////////
	context()->IASetPrimitiveTopology(current_primitive_topology);
	if (current_IA) {
		context()->IASetInputLayout(current_IA);
		current_IA->Release();
	}

#endif
}



void Leaves::computeLeafMatrix(XMFLOAT3 vPos, UINT leaf_index)
{	
		XMVECTOR pos = XMLoadFloat3(&vPos);

		float l = 0.5f;

		float max_slope = 1.0f;
		float min_slope = 0.01f;
		
		float y_min = 2.75f;
		float y_range = 1.0f;
		
		// y of the main leaf in [0,1] range (depending on height min,max)
		float height_norm = (XMVectorGetY(pos) - y_min) / y_range; // [0,1]
		
		// compute alpha for -(a*x)^2 which describes the main leaf shape
		float alpha = max_slope - (max_slope - min_slope) * height_norm; // [max_slope, min_slope]

		// h = -(a*l)^2
		float h = -alpha * l*l;
		
		XMVECTOR posH = pos;
		posH = XMVectorSetY(posH, 0.0f);
		XMVECTOR dir = XMVector3Normalize(posH);

		XMVECTOR res;
		res = XMVectorSet(XMVectorGetX(dir) * l, h, XMVectorGetZ(dir) * l, 1.0f);
		res += pos;
		
		XMFLOAT4 r;
		XMStoreFloat4(&r, res);
		r.w = 1.0f;
		///////

		// f(x) = -(ax)^2 => f'(x) = -2*a^2 * x
		float dL = -2.0f * alpha * alpha * l;

		XMVECTOR tangent = XMVectorSet(XMVectorGetX(dir), dL, XMVectorGetZ(dir), 0.0f);
		tangent = XMVector3Normalize(tangent);
		
		XMVECTOR up = XMVectorSet(0,1,0,0);
		XMVECTOR right = XMVector3Cross(up, tangent);
		up = XMVector3Cross(tangent, right);
		XMVECTOR position = XMLoadFloat4(&r);

		XMMATRIX m = XMMATRIX(right, up, tangent, position);
		XMStoreFloat4x4(&mtxLeaves[leaf_index], m);
		

		mtxLeaves[leaf_index]._11 = 1;
		mtxLeaves[leaf_index]._12 = 0;
		mtxLeaves[leaf_index]._13 = 0;

		mtxLeaves[leaf_index]._21 = 0;
		mtxLeaves[leaf_index]._22 = 1;
		mtxLeaves[leaf_index]._23 = 0;

		mtxLeaves[leaf_index]._31 = 0;
		mtxLeaves[leaf_index]._32 = 0;
		mtxLeaves[leaf_index]._33 = 1;

		XMMATRIX mIdentity = XMMatrixIdentity();
		XMStoreFloat4x4(&mtxLeaves[leaf_index], mIdentity);
}




